"""内置函数和类型配置模块

统一管理所有内置函数、类型映射和类方法配置
"""

import re
import ast

from . import basic_types
from . import global_functions
from . import str_module
from . import list_module
from . import dict_module
from . import set_module
from . import tuple_module
from . import optional_module
from . import copy_module
from . import exception_types
from mcpy.symbol_meta import Signature, Symbol, SymbolKind
from mcpy.template_param import TemplateParam
from typing import Dict, Any, List


def is_module_config(config):
    """判断配置是否为模块配置"""
    return config.get("is_module", False)


def parse_type_vars(
    type_vars_config: Dict[str, Dict[str, Any]],
) -> Dict[str, TemplateParam]:
    """解析 TYPE_VARS 配置为 TemplateParam 对象

    这是 BUILTIN 配置系统的工具函数，用于将 TYPE_VARS 字典转换为 TemplateParam 对象。

    Args:
        type_vars_config: TYPE_VARS 配置字典

    Returns:
        参数名到 TemplateParam 的映射

    示例：
        TYPE_VARS = {
            "T": {"description": "通用类型"},
            "T_numeric": {
                "description": "数值类型",
                "constraints": ["int", "float"],
            },
        }

        params = parse_type_vars(TYPE_VARS)
        # params["T"] = TemplateParam(name="T", constraint_kind=NONE)
        # params["T_numeric"] = TemplateParam(name="T_numeric", constraint_kind=UNION, ...)
    """
    result = {}
    for name, config in type_vars_config.items():
        result[name] = TemplateParam.from_type_var_config(name, config)
    return result


def extract_types_from_signature(signature: str) -> list[str]:
    """从函数签名中提取所有类型名称

    Args:
        signature: 函数签名字符串，如 "abs(x: T_numeric) -> T_numeric"

    Returns:
        提取的类型列表
    """
    import re

    # 匹配参数类型和返回类型
    type_pattern = r":\s*([A-Za-z_]\w*(?:\[.*?\])?)|(?:->)\s*([A-Za-z_]\w*(?:\[.*?\])?)"
    matches = re.findall(type_pattern, signature)
    types = set()
    for match in matches:
        type_name = match[0] or match[1]
        if type_name and type_name != "None":
            # 提取基础类型名（去除泛型参数）
            base_type = type_name.split("[")[0]
            types.add(base_type)
            # 提取泛型参数中的类型
            if "[" in type_name:
                generic_params = re.findall(r"\[([^\]]+)\]", type_name)
                for params in generic_params:
                    for param in params.split(","):
                        param = param.strip()
                        if param and param != "None":
                            types.add(param)
    return list(types)


def process_config_with_type_vars(config_module):
    """处理配置模块，自动识别并填充 type_vars

    现在将 TYPE_VARS 转换为 TemplateParam 对象，提供更强大的类型约束支持。

    Args:
        config_module: 配置模块对象

    Returns:
        处理后的配置字典
    """
    # 获取文件级 TYPE_VARS（如果存在）
    file_type_vars_dict = getattr(config_module, "TYPE_VARS", {})

    # 将 TYPE_VARS 转换为 TemplateParam 对象
    file_template_params = parse_type_vars(file_type_vars_dict)

    # 获取配置
    config = config_module.CONFIG.copy()

    # 处理每个函数/类型的配置
    for name, item_config in config.items():
        # 处理模块配置（is_module: True）
        if item_config.get("is_module") and "functions" in item_config:
            # 处理模块中的每个函数
            functions = item_config.get("functions", {})
            for func_name, func_config in functions.items():
                # 如果已经有 type_vars，跳过
                if "type_vars" in func_config and func_config["type_vars"]:
                    continue

                # 从签名中提取类型
                signatures = func_config.get("signatures", [])
                if not signatures:
                    continue

                used_types = set()
                for signature in signatures:
                    types = extract_types_from_signature(signature)
                    used_types.update(types)

                # 筛选出在 file_template_params 中定义的类型
                func_type_vars = {}
                for type_name in used_types:
                    if type_name in file_template_params:
                        # 保持向后兼容：仍然存储字典格式
                        func_type_vars[type_name] = file_type_vars_dict[type_name]

                # 自动填充 type_vars
                if func_type_vars:
                    func_config["type_vars"] = func_type_vars

        # 处理普通函数配置
        else:
            # 如果已经有 type_vars，跳过（允许显式覆盖）
            if "type_vars" in item_config and item_config["type_vars"]:
                continue

            # 从所有签名中提取类型
            signatures = item_config.get("signatures", [])
            if not signatures:
                continue

            used_types = set()
            for signature in signatures:
                types = extract_types_from_signature(signature)
                used_types.update(types)

            # 筛选出在 file_template_params 中定义的类型
            item_type_vars = {}
            for type_name in used_types:
                if type_name in file_template_params:
                    # 保持向后兼容：仍然存储字典格式
                    item_type_vars[type_name] = file_type_vars_dict[type_name]

            # 自动填充 type_vars（如果有识别到的模板参数）
            if item_type_vars:
                item_config["type_vars"] = item_type_vars

    # 将解析后的 TemplateParam 对象存储到配置中，供后续使用
    # 这是一个特殊的键，用于存储全局 TemplateParam 映射
    config["__template_params__"] = file_template_params

    return config


# 合并所有配置（支持文件级 TYPE_VARS）
BUILTIN_CONFIG = {}
# 全局 TemplateParam 注册表：所有模块的 TemplateParam 合并后的结果
GLOBAL_TEMPLATE_PARAMS = {}

for config_module in [
    basic_types,
    global_functions,
    str_module,
    list_module,
    dict_module,
    set_module,
    tuple_module,
    optional_module,
    copy_module,
    exception_types,
]:
    # 处理配置，自动识别 type_vars
    processed_config = process_config_with_type_vars(config_module)

    # 提取并合并 TemplateParam
    module_template_params = processed_config.pop("__template_params__", {})
    GLOBAL_TEMPLATE_PARAMS.update(module_template_params)

    for name, config in processed_config.items():
        if name in BUILTIN_CONFIG:
            # 如果已存在配置，合并而不是覆盖
            existing_config = BUILTIN_CONFIG[name]
            merged_config = existing_config.copy()
            merged_config.update(config)
            BUILTIN_CONFIG[name] = merged_config
        else:
            BUILTIN_CONFIG[name] = config


def is_global_function(config):
    """判断配置是否为全局函数"""
    # 如果配置包含 signatures 或 templates 字段，但不包含 cpp_type，则认为是全局函数
    # 如果同时包含 cpp_type，则认为是类型配置，其中的 signatures/templates 是类型转换
    has_function_fields = "signatures" in config or "templates" in config
    has_type_fields = "cpp_type" in config

    # 只有当有函数字段但没有类型字段时，才认为是全局函数
    return has_function_fields and not has_type_fields


def is_type_config(config):
    """判断配置是否为类型配置（包含类型映射、类方法或 Protocol）"""
    return "cpp_type" in config or config.get("is_protocol", False)


def extract_global_functions_config():
    """提取全局函数配置（兼容旧格式）"""
    return {
        name: config
        for name, config in BUILTIN_CONFIG.items()
        if is_global_function(config)
    }


def extract_type_configs():
    """提取类型配置（兼容旧格式）"""
    return {
        name: config
        for name, config in BUILTIN_CONFIG.items()
        if is_type_config(config)
    }


def get_type_includes(python_type):
    """获取类型所需的头文件"""
    config = BUILTIN_CONFIG.get(python_type)
    if config and "includes" in config:
        return config["includes"]
    return []


def is_template_type(python_type):
    """判断是否为模板类型（通过类型名称自动判断）"""
    return "[" in python_type and "]" in python_type


def get_default_value(python_type):
    """获取类型的默认值"""
    config = BUILTIN_CONFIG.get(python_type)
    if config and "default_value" in config:
        return config["default_value"]
    return None


def get_method_config(python_type, method_name):
    """获取类型方法的配置"""
    config = BUILTIN_CONFIG.get(python_type)
    if config and "methods" in config:
        return config["methods"].get(method_name)
    return None


def get_function_config(function_name):
    """获取全局函数的配置"""
    config = BUILTIN_CONFIG.get(function_name)
    if config and is_global_function(config):
        return config
    return None


def load_builtin_signatures():
    """将新的配置格式转换为Signature对象列表

    注意：这个函数是 builtin 体系的内部实现，它将 GLOBAL_TEMPLATE_PARAMS
    传递给签名解析函数，以便构建完整的 TemplateParam 信息。

    外部使用者（如符号表、类型系统）不应该直接依赖 GLOBAL_TEMPLATE_PARAMS，
    而应该使用 Signature 对象中已经包含的 template_params_detailed。
    """

    signatures = []

    # 将 GLOBAL_TEMPLATE_PARAMS 作为参数传递给解析函数
    # 这样解析函数不需要直接导入全局变量
    global_params = GLOBAL_TEMPLATE_PARAMS

    for name, config in BUILTIN_CONFIG.items():
        if is_global_function(config):
            # 处理全局函数
            if "signatures" in config:
                sig_list = config["signatures"]
                template_list = config.get("templates", [])

                for i, sig_str in enumerate(sig_list):
                    # 为每个签名匹配对应的模板
                    template = template_list[i] if i < len(template_list) else ""
                    signature = _parse_signature_string(
                        name, sig_str, config, template, global_params
                    )
                    if signature:
                        signatures.append(signature)
            elif "templates" in config:
                for template in config["templates"]:
                    signature = _parse_template_signature(name, template, config)
                    if signature:
                        signatures.append(signature)

        elif is_type_config(config):
            # 处理类型的构造函数（如 str(x: T) -> str）
            if "constructors" in config and "cpp_type" in config:
                constructor_config = config["constructors"]
                sig_list = constructor_config.get("signatures", [])
                template_list = constructor_config.get("templates", [])
                priority_config = constructor_config.get("priority", 0)

                # 检查 priority 是否是列表（每个签名有不同的优先级）
                is_priority_list = isinstance(priority_config, list)

                for i, sig_str in enumerate(sig_list):
                    # 为每个签名匹配对应的模板
                    template = template_list[i] if i < len(template_list) else ""

                    # 为每个签名创建独立的 config，包含对应的优先级和 callback
                    temp_config = {
                        **constructor_config,
                        "includes": constructor_config.get("includes", []),
                    }

                    # 设置当前签名的优先级
                    if is_priority_list:
                        temp_config["priority"] = (
                            priority_config[i]
                            if i < len(priority_config)
                            else (priority_config[0] if len(priority_config) > 0 else 0)
                        )
                    else:
                        temp_config["priority"] = priority_config

                    signature = _parse_signature_string(
                        name, sig_str, temp_config, template, global_params
                    )
                    if signature:
                        signatures.append(signature)

            # 处理类型根级别的全局函数（如 bool(list) -> !list.empty()）
            elif "signatures" in config and "cpp_type" in config:
                sig_list = config["signatures"]
                template_list = config.get("templates", [])

                for i, sig_str in enumerate(sig_list):
                    # 为每个签名匹配对应的模板
                    template = template_list[i] if i < len(template_list) else ""
                    signature = _parse_signature_string(
                        name, sig_str, config, template, global_params
                    )
                    if signature:
                        signatures.append(signature)

            # 处理类型的方法
            if "methods" in config:
                for method_name, method_config in config["methods"].items():
                    # 支持两种格式：
                    # 1. 字典格式：{"signatures": [...], "templates": [...]}
                    # 2. 列表格式：[{"signatures": [...], "templates": [...]}, ...]
                    if isinstance(method_config, list):
                        # 列表格式：每个元素是一个独立的方法配置
                        for config_item in method_config:
                            if "signatures" in config_item:
                                for i, sig_str in enumerate(config_item["signatures"]):
                                    signature = _parse_method_signature(
                                        name,
                                        method_name,
                                        sig_str,
                                        config_item,
                                        config,
                                        i,
                                        global_params,
                                    )
                                    if signature:
                                        signatures.append(signature)
                    elif "signatures" in method_config:
                        # 字典格式：单个方法配置
                        for i, sig_str in enumerate(method_config["signatures"]):
                            signature = _parse_method_signature(
                                name,
                                method_name,
                                sig_str,
                                method_config,
                                config,
                                i,
                                global_params,
                            )
                            if signature:
                                signatures.append(signature)

    return signatures


def _parse_function_signature_ast(sig_str):
    """使用AST解析函数签名字符串"""
    try:
        # 构造完整的函数定义
        if not sig_str.strip().startswith("def "):
            func_def = f"def {sig_str}:\n    pass"
        else:
            func_def = f"{sig_str}:\n    pass"

        # 解析AST
        tree = ast.parse(func_def)
        func_node = tree.body[0]

        if not isinstance(func_node, ast.FunctionDef):
            return []

        # 提取参数信息
        args = []
        param_types = []
        optional_params = []

        # 处理普通参数
        for i, arg in enumerate(func_node.args.args):
            args.append(arg.arg)

            # 获取类型注解
            if arg.annotation:
                param_type = _ast_to_string(arg.annotation)
            else:
                param_type = "Any"
            param_types.append(param_type)

        # 处理默认参数
        num_defaults = len(func_node.args.defaults)
        if num_defaults > 0:
            # 默认参数从后往前对应
            start_idx = len(func_node.args.args) - num_defaults
            for i in range(start_idx, len(func_node.args.args)):
                optional_params.append(i)

        # 处理可变参数 *args
        if func_node.args.vararg:
            args.append(func_node.args.vararg.arg)
            # 保存类型注解（如果有）
            if func_node.args.vararg.annotation:
                vararg_type = _ast_to_string(func_node.args.vararg.annotation)
                param_types.append(f"*{vararg_type}")  # 格式：*T_comparable
            else:
                param_types.append("*args")

        # 处理关键字参数 **kwargs
        if func_node.args.kwarg:
            args.append(func_node.args.kwarg.arg)
            # 保存类型注解（如果有）
            if func_node.args.kwarg.annotation:
                kwarg_type = _ast_to_string(func_node.args.kwarg.annotation)
                param_types.append(f"**{kwarg_type}")  # 格式：**dict_type
            else:
                param_types.append("**kwargs")

        # 获取返回类型
        return_type = "auto"
        if func_node.returns:
            return_type = _ast_to_string(func_node.returns)

        return [
            {
                "args": args,
                "param_types": param_types,
                "return_type": return_type,
                "optional_params": optional_params,
            }
        ]

    except Exception:
        return []


def _ast_to_string(node):
    """将AST节点转换为字符串"""
    if isinstance(node, ast.Name):
        return node.id
    elif isinstance(node, ast.Constant):
        return repr(node.value)
    elif isinstance(node, ast.Subscript):
        # 处理泛型类型，如 List[int]
        base = _ast_to_string(node.value)
        slice_val = _ast_to_string(node.slice)
        return f"{base}[{slice_val}]"
    elif isinstance(node, ast.Tuple):
        # 处理元组类型，如 Tuple[int, str]
        elements = [_ast_to_string(elt) for elt in node.elts]
        return ", ".join(elements)
    elif isinstance(node, ast.Attribute):
        # 处理属性访问，如 typing.List
        value = _ast_to_string(node.value)
        return f"{value}.{node.attr}"
    else:
        # 其他情况，尝试使用ast.unparse（Python 3.9+）或回退到字符串表示
        try:
            return ast.unparse(node)
        except AttributeError:
            return repr(node)


def _is_known_type_var(type_str: str, config: dict, known_template_params=None) -> bool:
    """检查是否是已知的类型变量（模板参数）

    Args:
        type_str: 类型字符串
        config: 配置对象（包含 type_vars）
        known_template_params: 已知的模板参数列表（从父类型继承，如 ['T'] 或 ['K', 'V']）

    Returns:
        bool: 是否是已知的类型变量

    识别优先级：
        1. 已知的父类型模板参数（如 set[T] 的 T）
        2. 配置中定义的 type_vars（该模块/类型专属）
        3. 全局 TYPE_VARS（通用的类型变量，如 T_numeric）
        4. 具体类型（如 Any, int, str）一律返回 False
    """
    # 具体类型（非模板参数）
    CONCRETE_TYPES = {
        "Any",
        "int",
        "str",
        "float",
        "bool",
        "None",
        "list",
        "dict",
        "set",
        "tuple",
    }

    if type_str in CONCRETE_TYPES:
        return False

    # 优先级1：检查是否在已知的模板参数中（从父类型继承）
    if known_template_params and type_str in known_template_params:
        return True

    # 优先级2：检查是否在配置的 TYPE_VARS 中定义
    type_vars = config.get("type_vars", {})
    if type_str in type_vars:
        return True

    # 优先级3：导入全局 TYPE_VARS
    from mcpy.builtin.builtin_table.global_functions import (
        TYPE_VARS as GLOBAL_TYPE_VARS,
    )

    if type_str in GLOBAL_TYPE_VARS:
        return True

    # 优先级4：不再使用启发式兜底规则
    #
    # 之前的启发式规则（如匹配 T1, T2, T_xxx）是错误的：
    # - 用户可以定义 class T1，破坏启发式机制
    # - 违背了配置驱动的设计原则
    #
    # 现在要求：所有使用的模板参数必须在以下位置明确定义：
    # 1. 全局 TYPE_VARS（global_functions.TYPE_VARS）
    # 2. 配置的 type_vars（函数/类型专属）
    # 3. known_template_params（从父类型继承）
    #
    # 如果都不匹配，说明不是模板参数
    return False


def _extract_template_params_auto(
    type_str, param_index, template_params, template_param_mapping, config=None
):
    """自动提取类型字符串中的模板参数（用于全局函数等无父类型的情况）

    Args:
        type_str: 类型字符串
        param_index: 参数索引
        template_params: 模板参数列表（输入/输出，包含已知的父类型模板参数）
        template_param_mapping: 模板参数位置映射（输出）
        config: 配置对象（包含 type_vars、template_params）
    """
    type_str = type_str.strip()
    config = config or {}

    # 检查是否是已知的类型变量
    if re.match(r"^[A-Z][A-Za-z0-9_]*$", type_str):
        # 传递已知的模板参数列表到检查函数
        if _is_known_type_var(type_str, config, template_params):
            # 是模板参数
            if type_str not in template_params:
                template_params.append(type_str)
            if type_str not in template_param_mapping:
                template_param_mapping[type_str] = {
                    "param_index": param_index,
                    "type_arg_index": -1,
                }
        # 否则是具体类型（如 Any），不处理
        return

    # 提取泛型参数
    type_args = _extract_type_args(type_str)
    if not type_args:
        return

    # 递归处理每个类型参数
    for type_arg_index, type_arg in enumerate(type_args):
        type_arg = type_arg.strip()

        # 检查是否是模板参数
        if re.match(r"^[A-Z][A-Za-z0-9_]*$", type_arg):
            if _is_known_type_var(type_arg, config, template_params):
                if type_arg not in template_params:
                    template_params.append(type_arg)
                if type_arg not in template_param_mapping:
                    template_param_mapping[type_arg] = {
                        "param_index": param_index,
                        "type_arg_index": type_arg_index,
                    }
        else:
            # 嵌套泛型，递归提取
            _extract_template_params_auto(
                type_arg, param_index, template_params, template_param_mapping, config
            )


def _extract_template_params_with_known_params(
    type_str, param_index, known_template_params, template_param_mapping
):
    """从类型字符串中提取模板参数，已知父类型的模板参数

    Args:
        type_str: 类型字符串，如 "list[tuple[K, V]]"
        param_index: 参数索引
        known_template_params: 已知的模板参数列表（如从 dict[K, V] 继承的 ['K', 'V']）
        template_param_mapping: 模板参数位置映射（输出）

    注意：此函数只记录位置映射，不再添加新的模板参数到列表中
    （因为模板参数已经从父类型中获取）
    """
    # 直接的模板参数（如 T）
    type_str = type_str.strip()
    if re.match(r"^[A-Z][A-Za-z0-9_]*$", type_str):
        # 检查是否是已知的模板参数
        if type_str in known_template_params:
            # 记录位置映射（直接参数）
            if type_str not in template_param_mapping:
                template_param_mapping[type_str] = {
                    "param_index": param_index,
                    "type_arg_index": -1,
                }
        return

    # 提取泛型参数
    type_args = _extract_type_args(type_str)
    if not type_args:
        return

    # 递归处理每个类型参数
    for type_arg_index, type_arg in enumerate(type_args):
        type_arg = type_arg.strip()

        # 如果是简单的模板参数（如 K, V）
        if re.match(r"^[A-Z][A-Za-z0-9_]*$", type_arg):
            # 检查是否是已知的模板参数
            if type_arg in known_template_params:
                # 只记录第一次出现的位置映射
                if type_arg not in template_param_mapping:
                    template_param_mapping[type_arg] = {
                        "param_index": param_index,
                        "type_arg_index": type_arg_index,
                    }
        else:
            # 嵌套泛型（如 tuple[K, V]），递归提取
            _extract_template_params_with_known_params(
                type_arg, param_index, known_template_params, template_param_mapping
            )


def _split_template_args(args_str: str) -> List[str]:
    """解析模板参数列表，支持嵌套泛型和可变参数

    Args:
        args_str: 模板参数列表字符串，如 "T, Args..." 或 "K, V" 或 "T, tuple[K, V]"

    Returns:
        List[str]: 参数列表，可变参数保留 "..." 后缀，如 ["T", "Args..."] 或 ["K", "V"]

    示例：
        "T, Args..." -> ["T", "Args..."]
        "K, V" -> ["K", "V"]
        "T, tuple[K, V]" -> ["T", "tuple[K, V]"]
        "T, tuple[K, V], Args..." -> ["T", "tuple[K, V]", "Args..."]
    """
    args = []
    bracket_count = 0
    current_arg = ""

    for i, char in enumerate(args_str):
        if char == "," and bracket_count == 0:
            if current_arg.strip():
                args.append(current_arg.strip())
            current_arg = ""
        else:
            if char == "[":
                bracket_count += 1
                current_arg += char
            elif char == "]":
                bracket_count -= 1
                current_arg += char
            else:
                current_arg += char

    if current_arg.strip():
        args.append(current_arg.strip())

    return args


def _extract_type_args(type_str):
    """从类型字符串中提取泛型参数

    Args:
        type_str: 类型字符串，如 "list[T]" 或 "dict[K, V]"

    Returns:
        List[str]: 泛型参数列表，如 ["T"] 或 ["K", "V"]，如果不是泛型则返回None
    """
    # 找到第一个 [ 的位置
    start_bracket = type_str.find("[")
    if start_bracket == -1:
        return None

    # 找到匹配的 ] 的位置
    bracket_count = 0
    end_bracket = -1

    for i in range(start_bracket, len(type_str)):
        if type_str[i] == "[":
            bracket_count += 1
        elif type_str[i] == "]":
            bracket_count -= 1
            if bracket_count == 0:
                end_bracket = i
                break

    if end_bracket == -1:
        return None

    # 提取括号内的内容
    args_str = type_str[start_bracket + 1 : end_bracket]

    # 使用新的 _split_template_args 函数分割参数
    return _split_template_args(args_str)


def _parse_signature_string(
    func_name, sig_str, config, template="", global_template_params=None
):
    """使用AST解析函数签名字符串，并构建详细的模板参数信息

    Args:
        func_name: 函数名
        sig_str: 签名字符串
        config: 配置字典
        template: 模板字符串
        global_template_params: 全局 TemplateParam 映射（可选），用于查找模板参数定义
    """
    try:
        # 使用AST解析函数签名
        parsed_signatures = _parse_function_signature_ast(sig_str)
        if not parsed_signatures:
            return None

        # 取第一个解析结果
        sig_data = parsed_signatures[0]

        # 提取模板参数并构建位置映射
        # 优先使用配置中明确指定的模板参数（如从父类型继承的 K, V）
        known_template_params = config.get("template_params", [])
        template_params = known_template_params[:] if known_template_params else []
        template_param_mapping = {}
        template_str = template or config.get("template", "")

        # 从参数类型中提取模板参数并记录位置
        for param_index, param_type in enumerate(sig_data["param_types"]):
            # 总是使用自动提取，这样可以处理签名中使用的额外模板参数（如 dict_keys[K]）
            # 如果有已知模板参数，它们已经在 template_params 中了
            _extract_template_params_auto(
                param_type, param_index, template_params, template_param_mapping, config
            )

        # 从返回类型中提取模板参数（不记录位置，因为返回类型不用于推导）
        return_type = sig_data["return_type"]
        # 检查是否是已知的类型变量
        if re.match(r"^[A-Z][A-Za-z0-9_]*$", return_type):
            if _is_known_type_var(return_type, config):
                if return_type not in template_params:
                    template_params.append(return_type)

        # 从模板字符串中提取模板参数（作为补充）
        # 匹配 {T}, {T_sized}, {T_numeric} 等
        if template_str:
            template_matches = re.findall(r"\{([A-Z][A-Za-z0-9_]*)\}", template_str)
            for match in template_matches:
                if match not in template_params:
                    template_params.append(match)

        # 提取 type_vars（类型约束信息）
        type_vars = config.get("type_vars", {})

        # ========== 重构：构建详细的模板参数信息 ==========
        # 构建 template_params_detailed：从 type_vars 和传入的 global_template_params 创建 TemplateParam 对象
        template_params_detailed = []
        for param_name in template_params:
            # 优先从配置的 type_vars 中查找
            if param_name in type_vars:
                template_param = TemplateParam.from_type_var_config(
                    param_name, type_vars[param_name]
                )
            # 回退到传入的全局模板参数（如果提供）
            elif global_template_params and param_name in global_template_params:
                template_param = global_template_params[param_name]
            # 无约束的通用模板参数
            else:
                template_param = TemplateParam(name=param_name)
            template_params_detailed.append(template_param)

        # 构建 template_inference_map：记录哪些模板参数可以从哪些函数参数推导
        # 格式：{"T": [0, 1]} 表示 T 可以从第 0 和第 1 个参数推导
        template_inference_map = {}
        for param_name, mapping_info in template_param_mapping.items():
            param_index = mapping_info.get("param_index", -1)
            if param_index >= 0:
                if param_name not in template_inference_map:
                    template_inference_map[param_name] = []
                # 避免重复
                if param_index not in template_inference_map[param_name]:
                    template_inference_map[param_name].append(param_index)
        # ========== 新增结束 ==========

        return Signature(
            function_name=func_name,
            param_types=sig_data["param_types"],
            return_type=sig_data["return_type"],
            template_params=template_params,
            emit_template=template_str,
            includes=config.get("includes", []),
            priority=config.get("priority", 0),
            args=sig_data["args"],
            optional_params=sig_data.get("optional_params", []),
            template_param_mapping=template_param_mapping,
            callback_path=config.get("callback"),  # 添加 callback 信息
            type_vars=type_vars,  # 传递类型约束信息（向后兼容）
            param_defaults=config.get("param_defaults", {}),  # 传递参数默认值
            optional_fragments=config.get("optional_fragments", {}),  # 传递可选参数片段
            # 新增字段
            template_params_detailed=template_params_detailed,
            template_inference_map=template_inference_map,
        )
    except Exception:
        return None


def _parse_template_signature(func_name, template, config):
    """解析模板签名"""

    try:
        # 提取 type_vars（类型约束信息）
        type_vars = config.get("type_vars", {})

        return Signature(
            function_name=func_name,
            param_types=template.get("param_types", []),
            return_type=template.get("return_type", "auto"),
            template_params=template.get("template_params", []),
            emit_template=template.get("template", config.get("template", "")),
            includes=config.get("includes", []),
            priority=config.get("priority", 0),
            callback_path=config.get("callback"),  # 添加 callback 信息
            type_vars=type_vars,  # 传递类型约束信息
        )
    except Exception:
        return None


def _parse_method_signature(
    type_name,
    method_name,
    sig_str,
    method_config,
    type_config,
    sig_index=0,
    global_template_params=None,
):
    """使用AST解析方法签名

    Args:
        type_name: 类型名
        method_name: 方法名
        sig_str: 签名字符串
        method_config: 方法配置
        type_config: 类型配置
        sig_index: 签名索引
        global_template_params: 全局 TemplateParam 映射（可选）
    """

    try:
        # 使用AST解析方法签名
        parsed_signatures = _parse_function_signature_ast(sig_str)
        if not parsed_signatures:
            return None

        # 取第一个解析结果
        sig_data = parsed_signatures[0]

        # 检查第一个参数是否为self，如果是则替换类型，否则添加self参数
        args = sig_data["args"]
        param_types = sig_data["param_types"]
        optional_params = sig_data.get("optional_params", [])

        # 识别 Literal 类型并提取常量参数
        constant_params = []
        for i, param_type in enumerate(param_types):
            if param_type.startswith("Literal[") and param_type.endswith("]"):
                # 提取基础类型: Literal[int] -> int
                base_type = param_type[8:-1]  # 去掉 "Literal[" 和 "]"
                param_types[i] = base_type
                # 记录该参数需要常量
                if i < len(args):
                    constant_params.append(args[i])

        # 检查是否为类方法（classmethod）
        is_classmethod = method_config.get("is_classmethod", False)

        # 提取基础类型名（用于方法索引）和模板参数（用于模板替换）
        # 例如：dict[K, V] -> base_type_name="dict", template_params=["K", "V"]
        # 例如：tuple[T, Args...] -> base_type_name="tuple", template_params=["T", "Args"]
        base_type_name = type_name.split("[")[0] if "[" in type_name else type_name
        template_params = []  # 向后兼容：简单字符串列表
        template_params_detailed = []  # 详细的模板参数定义
        variadic_param_index = None
        min_template_args = 0
        max_template_args = None
        type_match = re.search(r"\[([^\]]+)\]", type_name)
        if type_match:
            # 使用 _split_template_args 解析模板参数（支持可变参数）
            type_args = _split_template_args(type_match.group(1))
            for i, arg in enumerate(type_args):
                # 检查是否为可变参数
                is_variadic = arg.endswith("...")
                param_name = arg[:-3].strip() if is_variadic else arg.strip()

                # 向后兼容：只添加单个大写字母的参数到 template_params
                if re.match(r"^[A-Z]$", param_name):
                    template_params.append(param_name)

                # 构建详细的模板参数定义
                from mcpy.template_param import TemplateParam

                # 优先从配置的 type_vars 中查找（如果提供了 global_template_params）
                template_param = None
                if global_template_params and param_name in global_template_params:
                    template_param = global_template_params[param_name]
                    # 更新 is_variadic 字段
                    template_param.is_variadic = is_variadic
                else:
                    # 创建新的 TemplateParam
                    template_param = TemplateParam(
                        name=param_name, is_variadic=is_variadic
                    )

                template_params_detailed.append(template_param)

                if is_variadic:
                    variadic_param_index = i

            # 计算 min_template_args 和 max_template_args
            min_template_args = len(template_params_detailed)
            if variadic_param_index is not None:
                # 可变参数之前的参数是必需的
                min_template_args = variadic_param_index
                max_template_args = None  # 无限制
            else:
                max_template_args = min_template_args  # 固定数量

        # 对于泛型类型，保留完整的类型名作为 self 的类型，以便后续区分强类型和弱类型
        # 例如：tuple[T, Args...] -> param_types[0] = "tuple[T, Args...]"
        # 这样在查找时可以根据 owner_type 过滤签名
        self_type_name = type_name if "[" in type_name else base_type_name

        if args and args[0] == "self":
            # 第一个参数是self，使用完整的类型名（对于泛型类型）或基础类型名（对于非泛型类型）
            param_types[0] = self_type_name
        elif not is_classmethod:
            # 没有self参数，且不是类方法，添加到开头（使用完整的类型名）
            param_types = [self_type_name] + param_types
            args = ["self"] + args
            # 调整可选参数索引（因为添加了self参数）
            optional_params = [idx + 1 for idx in optional_params]
        else:
            # 类方法：第一个参数不是 self，但为了符号注册，需要在开头添加类型名
            # 这样 register_signature 可以从 param_types[0] 获取类型名
            # 但 args 保持原样（不添加 self）
            param_types = [self_type_name] + param_types

        # 获取模板字符串（优先使用templates列表中对应索引的模板，然后是template字段）
        template_str = ""
        if "templates" in method_config and method_config["templates"]:
            if sig_index < len(method_config["templates"]):
                template_str = method_config["templates"][sig_index]
            else:
                template_str = method_config["templates"][0]  # 回退到第一个模板
        else:
            template_str = method_config.get(
                "template", type_config.get("template", "")
            )

        # 获取优先级（支持数组形式）
        priority = 0
        if "priority" in method_config:
            priority_config = method_config["priority"]
            if hasattr(priority_config, "__getitem__") and hasattr(
                priority_config, "__len__"
            ):
                # 是列表或其他序列类型
                if sig_index < len(priority_config):
                    priority = priority_config[sig_index]
                else:
                    priority = (
                        priority_config[0] if len(priority_config) > 0 else 0
                    )  # 回退到第一个优先级
            else:
                priority = priority_config

        # 获取includes（优先使用方法级别的includes，然后是类型级别的includes）
        includes = method_config.get("includes", type_config.get("includes", []))

        # 提取 type_vars（类型约束信息，优先使用方法级别的type_vars）
        type_vars = method_config.get("type_vars", type_config.get("type_vars", {}))

        # 如果 template_params_detailed 还没有构建（非泛型类型的情况），现在构建
        if not template_params_detailed and template_params:
            from mcpy.template_param import TemplateParam

            for param_name in template_params:
                # 优先从配置的 type_vars 中查找
                if param_name in type_vars:
                    template_param = TemplateParam.from_type_var_config(
                        param_name, type_vars[param_name]
                    )
                # 回退到传入的全局模板参数（如果提供）
                elif global_template_params and param_name in global_template_params:
                    template_param = global_template_params[param_name]
                # 无约束的通用模板参数
                else:
                    template_param = TemplateParam(name=param_name)
                template_params_detailed.append(template_param)

            # 如果是在这里构建的，也需要计算 min/max
            if template_params_detailed:
                min_template_args = len(template_params_detailed)
                max_template_args = min_template_args

        # 对于方法，template_inference_map 通常为空，因为模板参数从类型继承
        # 但如果方法有自己的模板参数，可以从参数类型中推导
        template_inference_map = {}

        return Signature(
            function_name=method_name,
            param_types=param_types,
            return_type=sig_data["return_type"],
            template_params=template_params,
            emit_template=template_str,
            includes=includes,
            priority=priority,
            is_method=True,
            args=args,
            optional_params=optional_params,
            is_mutating=method_config.get("mutating", False),
            is_classmethod=is_classmethod,
            callback_path=method_config.get("callback"),
            type_vars=type_vars,  # 传递类型约束信息（向后兼容）
            # 新增字段
            template_params_detailed=(
                template_params_detailed if template_params_detailed else None
            ),
            template_inference_map=template_inference_map,
            constant_params=constant_params,  # 常量参数列表
            # 可变参数相关字段
            variadic_param_index=variadic_param_index,
            min_template_args=min_template_args,
            max_template_args=max_template_args,
        )
    except Exception:
        return None


# ============================================================================
# 统一的 Builtin 配置注册机制
# ============================================================================


def register_builtin_config(
    symbol_registry,
    config_name: str,
    config: dict,
    module_name: str = "builtins",
) -> list:
    """将 builtin 配置注册到符号注册表

    这是统一的注册入口，适用于：
    - 模块函数（如 copy.deepcopy）
    - 全局函数（如 len, print）
    - 类型方法（如 list.append）

    Args:
        symbol_registry: 目标符号注册表
        config_name: 配置名称（如 "copy", "dict[K, V]"）
        config: 配置字典
        module_name: 模块名称（如 "copy", "builtins"）

    Returns:
        需要添加的 includes 列表
    """
    includes = []

    # 1. 处理模块函数（is_module=True）
    if config.get("is_module") and "functions" in config:
        # 获取模块级的 includes
        module_includes = config.get("includes", [])

        for func_name, func_config in config["functions"].items():
            # 合并模块级和函数级的 includes
            merged_config = func_config.copy()
            func_includes = merged_config.get("includes") or []
            merged_config["includes"] = list(set(module_includes + func_includes))

            func_includes_result = _register_function_to_registry(
                symbol_registry, func_name, merged_config, module_name
            )
            includes.extend(func_includes_result)

    # 2. 处理类型方法（类型配置）
    elif "methods" in config:
        for method_name, method_config in config["methods"].items():
            method_includes = _register_method_to_registry(
                symbol_registry, config_name, method_name, method_config, config
            )
            includes.extend(method_includes)

    # 3. 处理全局函数（既不是模块也不是类型，但有 signatures）
    elif "signatures" in config and not config.get("cpp_type"):
        func_includes = _register_function_to_registry(
            symbol_registry, config_name, config, module_name
        )
        includes.extend(func_includes)

    # 4. 收集配置级的 includes
    if "includes" in config:
        includes.extend(config["includes"])

    return list(set(includes))  # 去重


def _register_function_to_registry(
    symbol_registry,
    func_name: str,
    func_config: dict,
    module_name: str,
) -> list:
    """注册函数到符号注册表

    Args:
        symbol_registry: 符号注册表
        func_name: 函数名称
        func_config: 函数配置
        module_name: 模块名称

    Returns:
        需要添加的 includes 列表
    """
    symbol = Symbol(
        name=func_name,
        kind=SymbolKind.FUNCTION,
        module=module_name,
    )

    # 解析并添加签名
    signatures = func_config.get("signatures", [])
    templates = func_config.get("templates", [])

    # 获取优先级配置（支持列表形式）
    priority_config = func_config.get("priority", 0)
    is_priority_list = hasattr(priority_config, "__getitem__") and hasattr(
        priority_config, "__len__"
    )

    for i, sig_str in enumerate(signatures):
        template = templates[i] if i < len(templates) else ""

        # 为每个签名创建独立的 config，包含对应的优先级
        temp_config = {
            **func_config,
            "includes": func_config.get("includes", []),
        }

        # 设置当前签名的优先级
        if is_priority_list:
            temp_config["priority"] = (
                priority_config[i]
                if i < len(priority_config)
                else (priority_config[0] if len(priority_config) > 0 else 0)
            )
        else:
            temp_config["priority"] = priority_config

        sig = _parse_signature_string(func_name, sig_str, temp_config, template)
        if sig:
            symbol.add_signature(sig)

    # 注册符号
    symbol_registry.register_function_symbol(symbol)

    return func_config.get("includes", [])


def _register_method_to_registry(
    symbol_registry,
    type_name: str,
    method_name: str,
    method_config: dict,
    type_config: dict,
) -> list:
    """注册类型方法到符号注册表

    Args:
        symbol_registry: 符号注册表
        type_name: 类型名称（如 "dict[K, V]"）
        method_name: 方法名称
        method_config: 方法配置
        type_config: 类型配置

    Returns:
        需要添加的 includes 列表
    """
    # 类型方法已经在 load_builtin_signatures() 中注册
    # 这里不需要重复注册，只返回 includes
    #
    # 注意：对于 builtin 模块，我们不应该尝试注册类型方法，
    # 因为模块只包含函数，不包含类型定义
    return method_config.get("includes", [])
